package com.marvels.financial.pay.kqpay.service.impl;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.marvels.common.constants.MarvelsConstant;
import com.marvels.common.dto.pay.McfeRepaymentTradeDetails;
import com.marvels.common.exception.MarvelsBusinessException;
import com.marvels.common.utils.MarvelsLogUtil;
import com.marvels.common.utils.ServerProperties;
import com.marvels.financial.pay.kqpay.dto.KqBindCardDTO;
import com.marvels.financial.pay.kqpay.dto.KqDirectPaymentDTO;
import com.marvels.financial.pay.kqpay.dto.KqDirectPaymentQueryDTO;
import com.marvels.financial.pay.kqpay.dto.KqPrebindCardDTO;
import com.marvels.financial.pay.kqpay.dto.TransInfo;
import com.marvels.financial.pay.kqpay.service.KqPayApi;
import com.marvels.financial.pay.kqpay.util.PayToKuanQian;
import com.marvels.financial.pay.kqpay.util.Post;
import com.marvels.financial.pay.kqpay.util.XMLUtil;
import com.marvels.system.common.dao.McsmRevealConfigureAppDao;
import com.marvels.system.common.dto.McsmRevealConfigureAppDTO;

import cn.hutool.core.util.StrUtil;

@Service
public class KqPayService implements KqPayApi{

	@Value("${config.properties.path}")
	private String configPropertiesPath;
	
	@Autowired
	private McsmRevealConfigureAppDao mcsmRevealConfigureAppDao;
	
	@Override
	public Map<String, Object> kuaiQianPrebindCard(KqPrebindCardDTO bindCardDTO) throws MarvelsBusinessException {
		MarvelsLogUtil.getInstance().info(">>>>>>>>>>预绑卡请求参数:" + JSON.toJSONString(bindCardDTO));
		if(StringUtils.isEmpty(bindCardDTO.getPan())){
			throw new MarvelsBusinessException("银行卡号不能为空");
		}
		if(StringUtils.isEmpty(bindCardDTO.getCardHolderName())){
			throw new MarvelsBusinessException("持卡人姓名不能为空");
		}
		if(StringUtils.isEmpty(bindCardDTO.getPhoneNO())){
			throw new MarvelsBusinessException("手机号不能为空");
		}
		if(StringUtils.isEmpty(bindCardDTO.getCardHolderId())){
			throw new MarvelsBusinessException("身份证不能为空");
		}
		if(StringUtils.isEmpty(bindCardDTO.getExternalRefNumber())){
			throw new MarvelsBusinessException("订单号不能为空");
		}
		//参数
		String terminalId = getKqTerminalId();
		String merchantId = getKqMerchantId();
		bindCardDTO.setTerminalId(terminalId);
		bindCardDTO.setMerchantId(merchantId);
		String requestUrl = ServerProperties.getValue(configPropertiesPath, "common.properties", "kq.ind.auth.url");
		
		// 转成xml
		String sendXml = XMLUtil.beantoXml(bindCardDTO, "1.0", "indAuthContent");
		TransInfo transInfo = new TransInfo();
		//设置手机动态鉴权节点
		transInfo.setMerchantId(merchantId);
	    transInfo.setRecordeText_1("indAuthContent");
		transInfo.setRecordeText_2("ErrorMsgContent");
		
		HashMap respXml = null;
		try {
			MarvelsLogUtil.getInstance().info(">>>>>>>>>>>>>快钱预绑卡请求报文:" + sendXml);
			respXml = Post.sendPost(requestUrl, sendXml ,transInfo);
			MarvelsLogUtil.getInstance().info(">>>>>>>>>>>>>快钱预绑卡返回参数:" + JSONObject.toJSONString(respXml));
		} catch (Exception e1) {
			MarvelsLogUtil.getInstance().error(">>>>>>>>>orderNumber" + bindCardDTO.getExternalRefNumber() + ",idNumber" + bindCardDTO.getCardHolderId() + "预绑卡请求异常:", e1);
			throw new MarvelsBusinessException("预绑卡请求异常");
		}
		Map<String, Object> result=new HashMap<String, Object>();
		if(respXml == null) {
			throw new MarvelsBusinessException("返回结果为空");
	    }else{
			//如果TR2获取的应答码responseCode的值为00时，成功
			if("00".equals((String)respXml.get("responseCode"))){
				result.put("token", respXml.get("token"));
				result.put("errormsg","成功");
				result.put("status","TO_VALIDATE");//沿用易宝的预绑卡订单状态  TO_VALIDATE  待短验
		    }else{
		    	result.put("errormsg", respXml.get("responseTextMessage"));
				result.put("status","BIND_FAIL");
		    }
			result.put("errorcode", respXml.get("responseCode"));
	    }
		return result;
	}

	@Override
	public Map<String, Object> kuaiQianBindCard(KqBindCardDTO bindCardDTO) throws MarvelsBusinessException {
		MarvelsLogUtil.getInstance().info(">>>>>>>>>>确定绑卡请求参数:" + JSON.toJSONString(bindCardDTO));
		//1 获取所需参数
		if(StringUtils.isEmpty(bindCardDTO.getValidCode())){
			throw new MarvelsBusinessException("验证码不能为空");
		}
		if(StringUtils.isEmpty(bindCardDTO.getExternalRefNumber())){
			throw new MarvelsBusinessException("订单号不能为空");
		}
		if(StringUtils.isEmpty(bindCardDTO.getToken())){
			throw new MarvelsBusinessException("安全校验值不能为空");
		}
		//参数
		String terminalId = getKqTerminalId();
		String merchantId = getKqMerchantId();
		bindCardDTO.setMerchantId(merchantId);
		bindCardDTO.setTerminalId(terminalId);
		String requestUrl=ServerProperties.getValue(configPropertiesPath, "common.properties", "kq.ind.auth.verify.url");
		
		// 转成xml
		String sendXml = XMLUtil.beantoXml(bindCardDTO, "1.0", "indAuthDynVerifyContent");
		TransInfo transInfo = new TransInfo();
		//设置手机动态鉴权节点
		transInfo.setMerchantId(merchantId);
		transInfo.setRecordeText_1("indAuthDynVerifyContent");
		transInfo.setRecordeText_2("ErrorMsgContent");

		HashMap respXml = null;
		try {
			//3.2 绑卡请求
			MarvelsLogUtil.getInstance().info(">>>>>>>>>>>>>快钱确定绑卡请求参数:" + sendXml);
			respXml = Post.sendPost(requestUrl, sendXml ,transInfo);
			MarvelsLogUtil.getInstance().info(">>>>>>>>>>>>>快钱确定绑卡返回参数:" + JSON.toJSONString(respXml));
		} catch (Exception e1) {
			MarvelsLogUtil.getInstance().error(">>>>>>>>>orderNumber" + bindCardDTO.getExternalRefNumber() + "确定绑卡请求异常:", e1);
		}
		Map<String, Object> result=new HashMap<String, Object>();
		if(respXml==null){
			throw new MarvelsBusinessException("返回结果为空");
	    }else{
			//如果TR2获取的应答码responseCode的值为00时，成功
			if("00".equals((String)respXml.get("responseCode")))
			{
				result.put("payToken", respXml.get("payToken"));
				result.put("errormsg","成功");
				result.put("status","BIND_SUCCESS");
		    }else{
		    	result.put("errormsg", respXml.get("responseTextMessage"));
				result.put("status","BIND_FAIL");
		    }
			result.put("errorcode", respXml.get("responseCode"));
	    }
		return result;
	}
	
	
	/**
	 * 获取快钱商户号
	 * @return
	 */
	private String getKqMerchantId(){
		String merchantNo = null;
		McsmRevealConfigureAppDTO config = mcsmRevealConfigureAppDao.queryConfigByKey("kq.merchant.id");
		if(config != null && config.getConfigValue() != null && config.getState() == 0){
			merchantNo = config.getConfigValue();
		}
		MarvelsLogUtil.getInstance().info("实时获取快钱商户号：" + merchantNo);
		return merchantNo;
	}

	/**
	 * 获取快钱终端号
	 * @return
	 */
	private String getKqTerminalId(){
		String merchantNo = null;
		McsmRevealConfigureAppDTO config = mcsmRevealConfigureAppDao.queryConfigByKey("kq.terminal.id");
		if(config != null && config.getConfigValue() != null && config.getState() == 0){
			merchantNo = config.getConfigValue();
		}
		MarvelsLogUtil.getInstance().info("实时获取快钱终端号：" + merchantNo);
		return merchantNo;
	}

	@Override
	public Map<String, Object> kuaiQianDirectPayment(KqDirectPaymentDTO directPaymentDTO)
			throws MarvelsBusinessException {
		MarvelsLogUtil.getInstance().info(">>>>>>>>>>快钱协议代扣请求参数:"+JSON.toJSONString(directPaymentDTO));
		String loanId = directPaymentDTO.getLoanId();
		
		String terminalId = getKqTerminalId();
		String merchantId = getKqMerchantId();
		directPaymentDTO.setTerminalId(terminalId);
		directPaymentDTO.setMerchantId(merchantId);
		
		String requestUrl=ServerProperties.getValue(configPropertiesPath, "common.properties", "kq.purchase.url");
		
		// 转成xml
		// 快钱的傻逼传参方式，忽略，都是写死的
		Map<String, Object> savePciFlag = new HashMap<String, Object>();
		savePciFlag.put("key", "savePciFlag");
		savePciFlag.put("value", "0");
		Map<String, Object> payBatch = new HashMap<String, Object>();
		payBatch.put("key", "payBatch");
		payBatch.put("value", "2");
		JSONArray array = new JSONArray();  
		array.add(savePciFlag);
		array.add(payBatch);
		JSONObject extDate = new JSONObject();
		extDate.put("extDate", array);
		directPaymentDTO.setExtMap(extDate);
		
		String sendXml = XMLUtil.beantoXml(directPaymentDTO, "1.0", "TxnMsgContent");
		TransInfo transInfo = new TransInfo();
		//设置手机动态鉴权节点
		transInfo.setMerchantId(merchantId);
		transInfo.setRecordeText_1("TxnMsgContent");
		transInfo.setRecordeText_2("ErrorMsgContent");
		
		Map<String, Object> result=new HashMap<String, Object>();
		HashMap respXml = null;
		try {
			MarvelsLogUtil.getInstance().info(">>>>>>>>>>>>>快钱协议代扣请求参数:" + sendXml);
			respXml = Post.sendPost(requestUrl, sendXml ,transInfo);
			MarvelsLogUtil.getInstance().info(">>>>>>>>>>>>>快钱协议代扣返回参数:" + JSONObject.toJSONString(respXml));
		} catch (Exception e1) {
			MarvelsLogUtil.getInstance().error(">>>>>>>>>loanId" + loanId + "快钱协议代扣请求异常:", e1);
			result.put("status",MarvelsConstant.PROCESSING);
			result.put("errormsg","协议代扣请求异常");
			return result;
		}
		
		if(respXml==null)
		{
			result.put("status",MarvelsConstant.PROCESSING);
			result.put("errormsg","返回结果为空");
	    }
	    else
	    {
			//如果TR2获取的应答码responseCode的值为00时，成功
	    	Object responseCode = respXml.get("responseCode");
	    	if(responseCode == null){
	    		result.put("status", MarvelsConstant.FAILED);
				result.put("errormsg", respXml.get("errorMessage"));
				result.put("errorcode", respXml.get("errorCode"));
	    	}else{
	    		String responseCodeStr = (String)responseCode;
				if("00".equals(responseCodeStr)){
					result.put("status",MarvelsConstant.SUCCESS);
					result.put("errormsg","交易成功");
				}else if(StrUtil.equalsAny(responseCodeStr, "C0", "68")){
					result.put("status", MarvelsConstant.PROCESSING);
					result.put("errormsg", respXml.get("responseTextMessage"));
				}else{
					result.put("status", MarvelsConstant.FAILED);
					result.put("errormsg", respXml.get("responseTextMessage"));
			    }
				result.put("r5_TrxNo", respXml.get("refNumber"));//支付平台流水号
				result.put("errorcode", respXml.get("responseCode"));
	    	}
	    }
		return result;
	}

	@Override
	public Map<String, Object> kuaiQianDirectPaymentQuery(KqDirectPaymentQueryDTO directPaymentQueryDTO)
			throws MarvelsBusinessException {
		MarvelsLogUtil.getInstance().info(">>>>>>>>>>快钱协议代扣结果查询请求参数:" + JSON.toJSONString(directPaymentQueryDTO));
		//参数
		String terminalId = getKqTerminalId();
		String merchantId = getKqMerchantId();
		directPaymentQueryDTO.setTerminalId(terminalId);
		directPaymentQueryDTO.setMerchantId(merchantId);
		String requestUrl= ServerProperties.getValue(configPropertiesPath, "common.properties", "kq.query.txn.url");
		
		// 转成xml
		String sendXml = XMLUtil.beantoXml(directPaymentQueryDTO, "1.0", "QryTxnMsgContent");
		TransInfo transInfo = new TransInfo();
		//设置手机动态鉴权节点
		transInfo.setMerchantId(merchantId);
		transInfo.setRecordeText_1("TxnMsgContent");
		transInfo.setRecordeText_2("ErrorMsgContent");
		
		Map<String, Object> result=new HashMap<String, Object>();
	
		HashMap respXml = null;
		try {
			MarvelsLogUtil.getInstance().info(">>>>>>>>>>>>>快钱直接支付查询请求参数:" + sendXml);
			respXml = Post.sendPost(requestUrl, sendXml ,transInfo);
			MarvelsLogUtil.getInstance().info(">>>>>>>>>>>>>快钱直接支付查询请求返回参数:" + JSONObject.toJSONString(respXml));
		} catch (Exception e1) {
			MarvelsLogUtil.getInstance().error(">>>>>>>>>origTransId" + directPaymentQueryDTO.getExternalRefNumber() + "协议代扣结果查询请求:", e1);
			result.put("status",MarvelsConstant.PROCESSING);
			result.put("errormsg","协议代扣结果查询请求异常");
			return result;
		}
		
		if(respXml == null)
		{
			result.put("status",MarvelsConstant.PROCESSING);
			result.put("errormsg", "返回结果为空");
	    }
	    else
	    {
	    	//如果TR2获取的应答码responseCode的值为00时，成功
	    	Object responseCode = respXml.get("responseCode");
	    	if(responseCode == null){
	    		result.put("status", MarvelsConstant.FAILED);
				result.put("errormsg", respXml.get("errorMessage"));
				result.put("errorcode", respXml.get("errorCode"));
	    	}else{
	    		String responseCodeStr = (String)responseCode;
				if("00".equals(responseCodeStr))
				{
					String txnStatus = (String)respXml.get("txnStatus");
					if("S".equals(txnStatus)){
						result.put("status", MarvelsConstant.SUCCESS);
						result.put("errormsg", "交易成功");
					}else if("F".equals(txnStatus)){
						result.put("status", MarvelsConstant.FAILED);
						result.put("errormsg", respXml.get("responseTextMessage"));
					}else{
						result.put("status",MarvelsConstant.PROCESSING);
						result.put("errormsg", respXml.get("responseTextMessage"));
					}   
				}else if(StrUtil.equalsAny(responseCodeStr, "C0", "68")){
					result.put("status", MarvelsConstant.PROCESSING);
					result.put("errormsg", respXml.get("responseTextMessage"));
				}else{
					result.put("status", MarvelsConstant.FAILED);
					result.put("errormsg", respXml.get("responseTextMessage"));
			    }
				result.put("r5_TrxNo", respXml.get("refNumber"));//支付平台流水号
				result.put("errorcode", respXml.get("responseCode"));
	    	}
	    }
		return result;
	}

	@Override
	public Map<String, Object> pay(McfeRepaymentTradeDetails tradeDetail) {
		Map<String, Object> resultMap = new HashMap<String,Object>();
		try {
			String remark = ServerProperties.getValue(configPropertiesPath, "common.properties", "kq.pay.remark");
			tradeDetail.setErrorMsg(remark);
			resultMap = PayToKuanQian.pay(ServerProperties.getValue(configPropertiesPath, "common.properties", "kq.pay.memberno"), ServerProperties.getValue(configPropertiesPath, "common.properties", "kq.send.pay.url"), tradeDetail);
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error("快钱代付异常", e);
			resultMap.put("result", "1");
			resultMap.put("errorCode",MarvelsConstant.PROCESSING);
			resultMap.put("errorMsg","支付异常,需要查询结果");
		}
		return resultMap;
	}

	@Override
	public Map<String, Object> payResultQuery(McfeRepaymentTradeDetails tradeDetail) {
		Map<String, Object> resultMap = new HashMap<String,Object>();
		try {
			resultMap = PayToKuanQian.payResultQuery(ServerProperties.getValue(configPropertiesPath, "common.properties", "kq.pay.memberno"), ServerProperties.getValue(configPropertiesPath, "common.properties", "kq.pay.result.query.url"), tradeDetail);
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error("快钱代付结果查询异常", e);
			resultMap.put("result", "1");
			resultMap.put("errorCode",MarvelsConstant.FAILED);
			resultMap.put("errorMsg","查询异常");
		}
		return resultMap;
	}
}
